package com.yan.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;


/**
 * 参数效验拦截器
 *
 * @Author WangYan
 * @Date 2021/6/11 11:34
 */
@Order(1000)
@Aspect
@Component
public class ParamsCheckAop {

    private Logger logger = LoggerFactory.getLogger(ParamsCheckAop.class);

    @Before("execution(*  com.yan.*.*.service.impl.*.*(..))")
    public void before(JoinPoint pjd) {
        Object[] args = pjd.getArgs();
        if (args.length > 0) {
            Object oneParam = args[0];
            String check = checkParam(oneParam);
            if (check != null) {
                logger.error("ParamsValidateException , class={}, method={}, msg={}", pjd.getTarget().getClass().getSimpleName(), pjd.getSignature().getName(), check);
//                throw new ParamsCheckException(1000, check);
                throw new RuntimeException(check);
            }
        }
    }

    private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    public <T> String checkParam(final T obj, final Class<?>... group) {
        List<String> list = new ArrayList<>();
        Set<ConstraintViolation<T>> constraintViolations = null;
        if (null == group) {
            constraintViolations = validator.validate(obj);
        } else {
            constraintViolations = validator.validate(obj, group);
        }
        final StringBuilder strBuilder = new StringBuilder();
        if (!constraintViolations.isEmpty()) {
            for (final ConstraintViolation<T> cv : constraintViolations) {
                if (!list.contains(String.valueOf(cv.getPropertyPath()))) {
                    list.add(String.valueOf(cv.getPropertyPath()));
                    strBuilder.append(cv.getMessage()).append(";");
                }
            }
            return strBuilder.toString();
        }
        return null;
    }


//    <!-- AOP -->
//        <dependency>
//            <groupId>org.aspectj</groupId>
//            <artifactId>aspectjrt</artifactId>
//        </dependency>
//        <dependency>
//            <groupId>org.aspectj</groupId>
//            <artifactId>aspectjweaver</artifactId>
//        </dependency>

//    <dependency>
//            <groupId>javax.validation</groupId>
//            <artifactId>validation-api</artifactId>
//            <version>2.0.1.Final</version>
//        </dependency>
}
